#ifndef __ULCORE_STATISTIC_H__
#define __ULCORE_STATISTIC_H__

#include "ULCore_History.h"
#include <list>

class ULC_BallFrequency{
public:
	int number;
	int appearedTimes;
	float rate;
public:
	ULC_BallFrequency();
	void CaculateRate(int totalTimes); // rate = apprearedTimes / totalTimes;
	bool operator==(const ULC_BallFrequency &ballFreq);
	bool operator>(const ULC_BallFrequency &ballFreq);
	bool operator<(const ULC_BallFrequency &ballFreq);
};

class ULC_PositionInfo{
private:
	list<ULC_BallFrequency>::iterator iter;
private:
	ULC_BallFrequency PopLowestRate(list<ULC_BallFrequency> &destList);
public:
	list<ULC_BallFrequency> numberOrder; //From minimum number to maximum number
	list<ULC_BallFrequency> rateOrder; //From lowest rate to highest rate
public:
	void ProcessNumber(int number);
	ULC_BallFrequency GetLowestRate();
	ULC_BallFrequency GetHighestRate();
	ULC_BallFrequency GetMinNumber();
	ULC_BallFrequency GetMaxNumber();
	int GetLowestRates(list<ULC_BallFrequency> &lowestRates, int &count); //Callers must check count after method returns to get the correct length
	int GetHighestRates(list<ULC_BallFrequency> &lowestRates, int &count);
	int GetMinNumbers(list<ULC_BallFrequency> &minNumbers, int &count);
	int GetMaxNumbers(list<ULC_BallFrequency> &minNumbers, int &count);
public:
	int Sort(); //Sort numberOrder and rateOrder
	void SetupRates(int totalSerials);
	friend ostream& operator<<(ostream &os, ULC_PositionInfo &posInfo);
};

class ULC_Statistic{
private:
	int totalSerials;
	ULC_PositionInfo redsStatistic[UL_RED_BALLS_COUNT];
	ULC_PositionInfo redsStatisticOut[UL_RED_BALLS_COUNT];
	ULC_PositionInfo blueStatistic;
private:
	int ParseSerial(ULC_Serial &serial);
public:
	ULC_Statistic();
	ULC_Statistic(ULC_History &historyData);//Statistic for whole serials
	ULC_Statistic(int nSerials, ULC_Serial *serials); //Can be used as a statistic for serials within a specific range
	int ParseHistoryData(ULC_History &historyData);
	int ParseSerials(int nSerials, ULC_Serial *serials);
	friend ostream& operator<<(ostream &os, ULC_Statistic &stat);
public:
	ULC_PositionInfo *GetSortedRedInfo(int index); //"index"'s range: 0 - 5
	ULC_PositionInfo *GetOutRedInfo(int index);
	ULC_PositionInfo *GetBlueInfo();
};

#endif /*__ULCORE_STATISTIC_H__*/
